<template>
  <div class="vix-section">
    <u-row flex>
      <u-col flex="460px" style="padding-right: 16px">
        <u-tree
          :tree-data="treeData"
          default-expand-all
          @select="handleTreeSelect"
        >
          <template #title="{ node }">
            <u-tag
              v-if="node.key !== 'root'"
              class="menu-tree-tag"
              :color="`${getEnumDisplay(node.category, authCategoryOptions, {
                value: 'value',
                label: 'color'
              })}`"
            >
              {{ getEnumDisplay(node.category, authCategoryOptions) }}
            </u-tag>
            <span>{{ node.name }}</span>
          </template>
          <template #operateBox="{ node }">
            <div v-if="node.key === 'root'" class="tree-operate-wrapper">
              <u-button
                size="small"
                type="primary"
                class="tree-operate-btn"
                @click.stop="handleAddChild(node)"
              >
                <u-icon type="add" />
              </u-button>
            </div>
            <div v-else class="tree-operate-wrapper">
              <u-button
                size="small"
                class="tree-operate-btn"
                @click.stop="handleAddChild(node)"
              >
                <u-icon type="add" />
              </u-button>
              <u-button
                size="small"
                class="tree-operate-btn"
                @click="handleDelete(node)"
              >
                <u-icon type="remove" />
              </u-button>
            </div>
          </template>
        </u-tree>
      </u-col>
      <u-col flex="1 1 auto">
        <dynamics-form
          ref="formRef"
          :model="formData"
          :setting="formSetting"
          :wrapper-width="280"
        >
          <u-form-item>
            <u-button type="primary" :loading="saveLoading" @click="handleSave">
              保存
            </u-button>
          </u-form-item>
        </dynamics-form>
      </u-col>
    </u-row>
  </div>
</template>

<script>
import { ref } from 'vue'
import {
  getAuthListApi,
  addAuthApi,
  updateAuthApi,
  deleteAuthApi
} from '@api/author'

import {
  DynamicsForm, Modal, message, libs
} from '@bairong/vix'
import { authCategoryOptions } from '@/libs/data/enums'

const { getEnumDisplay } = libs.conversion

const ROOT_NAME = '根节点'

export default {
  name: 'AuthManage',
  components: {
    DynamicsForm
  },
  setup() {
    const authData = ref([])
    const treeData = ref([])

    const buildTree = () => {
      const deepBuildTree = (node, level = 2) => {
        const children = authData.value
          .filter(x => x.parentId === node.id)
          .map(x => ({ ...x, key: x.id, level }))
          .sort((a, b) => a.sort - b.sort)
        node.children = children
        node.children.forEach(n => {
          deepBuildTree(n, level + 1)
        })
      }

      const lv1 = authData.value
        .filter(x => x.parentId === 0)
        .map(x => ({ ...x, key: x.id, level: 1 }))
        .sort((a, b) => a.sort - b.sort)
      lv1.forEach(n => {
        deepBuildTree(n)
      })
      const children = lv1 || []
      treeData.value = [{ name: ROOT_NAME, key: 'root', children }]
    }
    // 获取远端数据后，形成树结构数据
    const getAuthData = () => {
      getAuthListApi().then(data => {
        authData.value = data
        // 这里根据读取数据形成菜单树
        buildTree()
      })
    }

    getAuthData()

    const initModel = () => ({
      category: 1, // 1 菜单 2 页面 3 按钮
      name: '', // 资源名
      englishName: '', // 英文名
      authority: '', // 权限名
      url: '', // 路径
      sort: '1',
      parentId: 0,
      parentName: '根节点'
    })
    const formRef = ref(null)
    const formData = ref(initModel())
    const formSetting = ref([
      {
        name: 'parentName',
        label: '父级菜单',
        placeholder: '父级菜单',
        type: 'input',
        disabled: true,
        rules: [{ required: false, message: '请填写姓名', trigger: 'blur' }]
      },
      {
        name: 'category',
        label: '类型',
        placeholder: '',
        type: 'radioGroup',
        options: authCategoryOptions,
        rules: [
          {
            required: true,
            message: '请选择类型',
            trigger: 'change',
            type: 'number'
          }
        ]
      },
      {
        name: 'name',
        label: '权限名称',
        placeholder: '请输入权限名称',
        type: 'input',
        rules: [{ required: true, message: '请输入权限名称', trigger: 'blur' }]
      },
      {
        name: 'englishName',
        label: '英文名',
        placeholder: '请输入英文名',
        type: 'input',
        rules: [{ required: true, message: '请输入英文名', trigger: 'blur' }]
      },
      {
        name: 'authority',
        label: '权限名',
        placeholder: '请输入权限名',
        type: 'input',
        rules: [{ required: true, message: '请输入权限名', trigger: 'blur' }]
      },
      {
        name: 'url',
        label: '路径',
        placeholder: '请输入路径',
        type: 'input',
        rules: [{ required: true, message: '请输入路径', trigger: 'blur' }]
      },
      {
        name: 'sort',
        label: '排序',
        placeholder: '请输入排序',
        type: 'input',
        rules: [
          { required: true, message: '请填写排序', trigger: 'blur' },
          {
            pattern: /^[1-9]([0-9]+)?$/,
            message: '请填写数字',
            trigger: 'blur'
          }
        ]
      }
    ])
    const operateType = ref('add')
    const saveLoading = ref(false)
    const selectNode = ref(null)

    const handleTreeSelect = items => {
      const data = items[0]
      if (data.key === 'root') {
        return
      }
      selectNode.value = data.id
      operateType.value = 'edit'
      const {
        id,
        name,
        category,
        englishName,
        authority,
        url,
        sort,
        parentId
      } = data
      let parentName = ''
      if (parentId === 0) {
        parentName = ROOT_NAME
      } else {
        parentName = authData.value.find(x => x.id === parentId).name
      }
      formRef.value.resetFields()
      formData.value = {
        id,
        name,
        englishName,
        category,
        authority,
        url,
        parentId,
        sort: sort.toString(),
        parentName
      }
    }

    const clearForm = () => {
      formRef.value.resetFields()
    }
    // 添加子菜单事件
    const handleAddChild = node => {
      operateType.value = 'add'
      formData.value = initModel()
      if (node.key === 'root') {
        formData.value.parentId = 0
        formData.value.parentName = ROOT_NAME
      } else {
        formData.value.parentId = node.id
        formData.value.parentName = node.name
      }
    }

    const handleSave = () => {
      formRef.value.validate().then(() => {
        const {
          id,
          name,
          category,
          englishName,
          authority,
          url,
          sort,
          parentId
        } = formData.value
        const params = {
          id,
          name,
          englishName,
          authority,
          parentId,
          url,
          sort,
          category
        }
        saveLoading.value = true;

        (operateType.value === 'add' ? addAuthApi : updateAuthApi)(params)
          .then(() => {
            saveLoading.value = false
            message.success('保存成功')
            getAuthData()
            if (operateType.value === 'add') {
              clearForm()
            }
          })
          .catch(err => {
            saveLoading.value = false
            message.error(err)
          })
      })
    }

    // 删除权限事件
    const handleDelete = node => {
      Modal.confirm({
        title: '删除',
        loading: true,
        content: '确定删除该权限吗？',
        onOk: () => {
          deleteAuthApi({ resourceId: node.id })
            .then(() => {
              message.success('删除成功')
              Modal.remove()
              getAuthData()
            })
            .catch(err => {
              message.error(err)
              Modal.remove()
            })
        }
      })
    }

    return {
      treeData,
      formRef,
      formData,
      formSetting,
      saveLoading,
      handleTreeSelect,
      handleAddChild,
      handleDelete,
      handleSave,
      getEnumDisplay,
      authCategoryOptions
    }
  }
}
</script>
